PAE page directories must be below 4GB. Based on a patch
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 11 Aug 2005 10:34:32 +0000 (10:34 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 11 Aug 2005 10:34:32 +0000 (10:34 +0000)
from Gerd Knorr.
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
xen/arch/x86/domain_build.c
xen/arch/x86/mm.c
xen/include/asm-x86/page.h

index 79b4c2b79f90dbdf1aad785c23e38d2ac0e8344c..fcf97c79e4729c227f72cb75b9870c065b85e95c 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/mmu_context.h>
 
 #include <asm-xen/foreign_page.h>
+#include <asm-xen/hypervisor.h>
 
 void show_mem(void)
 {
@@ -274,6 +275,11 @@ void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
 {
        unsigned long flags;
 
+#ifdef CONFIG_X86_PAE
+       /* this gives us a page below 4GB */
+       xen_contig_memory((unsigned long)pgd, 0);
+#endif
+
        if (!HAVE_SHARED_KERNEL_PMD)
                spin_lock_irqsave(&pgd_lock, flags);
 
index 6e7b022032886be6d341e74357c36657fe31f170..9ba5b4512bfba8f07f32091021fe9fd83463ed72 100644 (file)
@@ -74,7 +74,7 @@ int construct_dom0(struct domain *d,
                    unsigned long _initrd_start, unsigned long initrd_len,
                    char *cmdline)
 {
-    int i, rc, dom0_pae, xen_pae;
+    int i, rc, dom0_pae, xen_pae, order;
     unsigned long pfn, mfn;
     unsigned long nr_pages;
     unsigned long nr_pt_pages;
@@ -143,10 +143,6 @@ int construct_dom0(struct domain *d,
         nr_pages = avail_domheap_pages() +
             ((initrd_len + PAGE_SIZE - 1) >> PAGE_SHIFT) +
             ((image_len  + PAGE_SIZE - 1) >> PAGE_SHIFT);
-    if ( (page = alloc_largest(d, nr_pages)) == NULL )
-        panic("Not enough RAM for DOM0 reservation.\n");
-    alloc_spfn = page_to_pfn(page);
-    alloc_epfn = alloc_spfn + d->tot_pages;
 
     if ( (rc = parseelfimage(&dsi)) != 0 )
         return rc;
@@ -215,8 +211,15 @@ int construct_dom0(struct domain *d,
 #endif
     }
 
-    if ( ((v_end - dsi.v_start) >> PAGE_SHIFT) > (alloc_epfn - alloc_spfn) )
-        panic("Insufficient contiguous RAM to build kernel image.\n");
+    order = get_order(v_end - dsi.v_start);
+    if ( (1UL << order) > nr_pages )
+        panic("Domain 0 allocation is too small for kernel image.\n");
+
+    /* Allocate from DMA pool: PAE L3 table must be below 4GB boundary. */
+    if ( (page = alloc_domheap_pages(d, order, ALLOC_DOM_DMA)) == NULL )
+        panic("Not enough RAM for domain 0 allocation.\n");
+    alloc_spfn = page_to_pfn(page);
+    alloc_epfn = alloc_spfn + d->tot_pages;
 
     printk("PHYSICAL MEMORY ARRANGEMENT:\n"
            " Dom0 alloc.:   %"PRIphysaddr"->%"PRIphysaddr,
index 34b282b230a121b3dde26eaff6391536f015ae50..827aa23463134e9f8c5cc762527b8653cd5be815 100644 (file)
@@ -856,6 +856,14 @@ static int alloc_l3_table(struct pfn_info *page, unsigned long type)
 
     ASSERT(!shadow_mode_refcounts(d));
 
+#ifdef CONFIG_X86_PAE
+    if ( pfn >= 0x100000 )
+    {
+        MEM_LOG("PAE pgd must be below 4GB (0x%lx >= 0x100000)", pfn);
+        return 0;
+    }
+#endif
+
     pl3e = map_domain_page(pfn);
     for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ )
     {
index 0ac2ab42b04d1fd0e28d0b33272af9d919e1f3d3..71edad153029a55e96bc5f8ea433db2829782813 100644 (file)
@@ -283,13 +283,9 @@ extern void paging_init(void);
 static __inline__ int get_order(unsigned long size)
 {
     int order;
-    
-    size = (size-1) >> (PAGE_SHIFT-1);
-    order = -1;
-    do {
+    size = (size-1) >> PAGE_SHIFT;
+    for ( order = 0; size; order++ )
         size >>= 1;
-        order++;
-    } while (size);
     return order;
 }